package com.unitedvision.persistence.domain;

import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.unitedvision.core.domain.CompanyBill;
import com.unitedvision.core.domain.CompanyBillingStatus;
import com.unitedvision.core.exception.WrongFormatException;

@Entity
@Table (name = "company_bill")
public class CompanyBillEntity {
	private int id;
	private CompanyEntity company;
	private PeriodeValue periode;
	private long bill;
	private long billPaid;
	private CompanyBillingStatus status;
	
	public CompanyBillEntity() {
		super();
	}

	public CompanyBillEntity(CompanyBill companyBill) throws WrongFormatException {
		super();
		this.id = companyBill.getId();
		this.company = CompanyEntity.create(companyBill.getCompany());
		this.periode = PeriodeValue.create(companyBill.getPeriode());
		this.bill = companyBill.getBill();
		this.billPaid = companyBill.getBillPaid();
		this.status = companyBill.getBillingStatus();
	}

	public CompanyBillEntity(CompanyEntity company, PeriodeValue periode, long bill, long billPaid, CompanyBillingStatus billingStatus) {
		super();
		this.company = company;
		this.periode = periode;
		this.bill = bill;
		this.billPaid = billPaid;
		this.status = billingStatus;
	}

	@Id @GeneratedValue
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@ManyToOne (fetch = FetchType.EAGER)
	@JoinColumn (name = "company_id", referencedColumnName = "id")
	public CompanyEntity getCompany() {
		return company;
	}

	public void setCompany(CompanyEntity company) {
		this.company = company;
	}

	@Embedded
	public PeriodeValue getPeriode() {
		return periode;
	}

	public void setPeriode(PeriodeValue periode) {
		this.periode = periode;
	}

	@Column (name = "bill")
	public long getBill() {
		return bill;
	}

	public void setBill(long bill) {
		this.bill = bill;
	}

	@Column (name = "bill_paid")
	public long getBillPaid() {
		return billPaid;
	}

	public void setBillPaid(long billPaid) {
		this.billPaid = billPaid;
	}

	@Column (name = "billing_status")
	public CompanyBillingStatus getStatus() {
		return status;
	}

	public void setStatus(CompanyBillingStatus billingStatus) {
		this.status = billingStatus;
	}

	@Transient
	public String getName() {
		return company.getName();
	}

	@Transient
	public AddressValue getAddress() {
		return company.getAddress();
	}

	@Transient
	public ContactValue getContact() {
		return company.getContact();
	}
	
	public CompanyBill toCompanyBill() {
		return new CompanyBill(id, company.toCompany(), periode.toPeriode(), bill, billPaid, status);
	}
	
	public static CompanyBillEntity create(CompanyEntity company, PeriodeValue periode, long bill, long billPaid, CompanyBillingStatus billingStatus) {
		return new CompanyBillEntity(company, periode, bill, billPaid, billingStatus);
	}

	public static CompanyBillEntity create(CompanyBill bill) throws WrongFormatException {
		return new CompanyBillEntity(bill);
	}

	@Override
	public String toString() {
		return "CompanyBillEntity [id=" + id + ", company=" + company
				+ ", periode=" + periode + ", bill=" + bill + ", billPaid="
				+ billPaid + ", status=" + status + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (bill ^ (bill >>> 32));
		result = prime * result + (int) (billPaid ^ (billPaid >>> 32));
		result = prime * result
				+ ((status == null) ? 0 : status.hashCode());
		result = prime * result + ((company == null) ? 0 : company.hashCode());
		result = prime * result + id;
		result = prime * result + ((periode == null) ? 0 : periode.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		CompanyBillEntity other = (CompanyBillEntity) obj;
		if (bill != other.bill)
			return false;
		if (billPaid != other.billPaid)
			return false;
		if (status != other.status)
			return false;
		if (company == null) {
			if (other.company != null)
				return false;
		} else if (!company.equals(other.company))
			return false;
		if (id != other.id)
			return false;
		if (periode == null) {
			if (other.periode != null)
				return false;
		} else if (!periode.equals(other.periode))
			return false;
		return true;
	}
}
